﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

namespace CommonNet48.DBUtils.SqlSugar
{
    /// <summary>
    /// 数据仓库类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class Repository<T> : SimpleClient<T> where T : class, new()
    {
        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="context">上下文</param>
        public Repository(ISqlSugarClient context = null) : base(context)//注意这里要有默认值等于null
        {
            if (base.Context == null)
            {
                db = new SqlSugarClient(new ConnectionConfig()
                {
                    ConfigId = "0",
                    DbType = GetDbType(),
                    InitKeyType = InitKeyType.Attribute,
                    IsAutoCloseConnection = true,
                    ConnectionString = GetConnectionString(),
                    ////AOP注册  APO详见:https://www.donet5.com/home/Doc?typeId=1204
                    AopEvents = new AopEvents
                    {
                        OnLogExecuting = (sql, p) =>
                        {
                            Console.WriteLine(sql);
                            Console.WriteLine(string.Join(",", p?.Select(it => it.ParameterName + ":" + it.Value)));
                        }
                    }
                });
                base.Context = this.db;

            }
        }

        /// <summary>
        /// 添加多库
        /// </summary>
        /// <param name="cfg"></param>
        public virtual void AddConnection(ConnectionConfig cfg)
        {
            this.db.AddConnection(cfg);
            base.Context = this.db;

        }

        /// <summary>
        /// 获取数据库操作子对象
        /// </summary>
        /// <param name="configId">数据对象ID(ConfigId值)</param>
        /// <returns></returns>
        public virtual SqlSugarProvider GetConnection(dynamic configId)
        {
            return this.db.GetConnection(configId);
        }




        /// <summary>
        /// SqlSugarClient对象
        /// </summary>
        protected SqlSugarClient db = null;

        /// <summary>
        /// 数据库连接字符串
        /// </summary>
        private readonly string _ConnectionString = $"Data Source = {Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data", "Broadex.S3")}";

        /// <summary>
        /// 数据库类型
        /// </summary>
        private readonly DbType _DBType = DbType.Sqlite;

        /// <summary>
        /// 获取数据库类型
        /// </summary>
        /// <returns></returns>
        protected virtual DbType GetDbType()
        {
            return _DBType;
        }

        /// <summary>
        /// 获取数据库连接字符串
        /// </summary>
        /// <returns></returns>
        protected virtual string GetConnectionString()
        {
            return _ConnectionString;
        }

        /// <summary>
        /// 获取服务器时间
        /// </summary>
        /// <returns></returns>
        public DateTime GetTime()
        {
            return Context.GetDate();
        }

        /// <summary>
        /// 分表插入
        /// </summary>
        /// <param name="obj">插入对象</param>
        /// <returns></returns>
        public virtual bool SplitInsert(T obj)
        {
            return base.Context.Insertable(obj).SplitTable().ExecuteCommand() == 1;
        }
        /// <summary>
        /// 分表插入(雪花ID)
        /// </summary>
        /// <param name="obj">插入对象</param>
        /// <returns></returns>
        public virtual bool SplitInsertRetSnowID(T obj)
        {
            return base.Context.Insertable(obj).SplitTable().ExecuteReturnSnowflakeId() >= 0;
        }

        /// <summary>
        /// 插入数据(雪花ID)
        /// </summary>
        /// <param name="obj">插入对象</param>
        /// <returns></returns>
        public virtual bool InsertRetSnowID(T obj)
        {
            return base.Context.Insertable<T>(obj).ExecuteReturnSnowflakeId() >= 0;
        }

        /// <summary>
        /// 逻辑删除(根据主键值)
        /// </summary>
        /// <typeparam name="Tid">主键类型</typeparam>
        /// <param name="id">主键值</param>
        public virtual void DeleteObjLogicByID<Tid>(Tid id)
        {
            Context.Deleteable<T>().In(id).IsLogic().ExecuteCommand();
        }

        /// <summary>
        /// 逻辑删除对象
        /// </summary>
        /// <param name="obj">删除的对象</param>
        public virtual void DeleteObjLogic(T obj)
        {
            Context.Deleteable<T>(obj).IsLogic().ExecuteCommand();
        }


        /// <summary>
        /// 更新对象
        /// </summary>
        /// <param name="newObj">新的对象</param>
        /// <returns></returns>
        public virtual bool UpdateObj(T newObj)
        {
            return Context.Updateable(newObj).ExecuteCommand() == 1;
        }

        /// <summary>
        /// 分表更新
        /// </summary>
        /// <param name="newObj">新的对象</param>
        /// <returns></returns>
        public virtual bool SplitUpdate(T newObj)
        {
            return Context.Updateable<T>(newObj).SplitTable().ExecuteCommand() == 1;
        }



    }
}
